/**
 * 创建canvas
 * @param {Object} attrs
 * @returns {Object}
 */
const createCanvas = (attrs = {}) => {
    let canvas = document.createElement('canvas')
    Object.keys(attrs).forEach(key => {
        canvas.setAttribute(key, attrs[key])
    })
    return canvas
}

/**
 * 创建Img
 * @param src 图片地址
 * @param
 */
const createImg = src => {
    return new Promise(resolve => {
        const img = new Image()
        img.crossOrigin = 'Anonymous'
        img.onload = () => {
            resolve(img)
        }
        img.setSrc = url => {
            img.src = url
        }
        img.setSrc(src)
    })
}

/**
 * 文件分片上传
 * @param file
 * @return Promise
 */
export const fileUploadByShard = ({ file }) => {
    return new Promise((resolve, reject) => {
        resolve()
    })
}

/**
 * 文件单位显示转换
 * @param bytes
 */
export const bytesToSize = (bytes = 0) => {
    if (bytes === 0) return '0 B'
    const k = 1024
    const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
    let i = Math.floor(Math.log(bytes) / Math.log(k))
    return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + units[i]
}

/**
 * 文件下载
 * @param fileName 文件名称
 * @param content 文件流内容 || url
 * @param isStream 是否为流下载
 */
export const download = ({ fileName, content }) => {
    const blob = new Blob([content])
    if ('download' in document.createElement('a')) {
        //非IE下载
        const elink = document.createElement('a')
        elink.download = fileName
        elink.style.display = 'none'
        elink.href = URL.createObjectURL(blob)
        elink.addEventListener('click', e => {
            e.stopImmediatePropagation()
        })
        document.body.appendChild(elink)
        elink.click()
        URL.revokeObjectURL(elink.href) //释放URL 对象
        document.body.removeChild(elink)
    } else {
        //IE10+下载
        navigator.msSaveBlob(blob, fileName)
    }
}

/**
 * 获取base64
 * @returns Promise
 */
export const getBase64 = file => {
    return new Promise(resolve => {
        const fr = new FileReader()
        fr.onload = e => {
            resolve(e.target.result, e)
        }
        fr.readAsDataURL(file)
    })
}

/**
 * base64转Blob
 * @param {Sring|Array} base64 文件base64
 * @return {String|Array} blob
 */
export const base64ToBlob = base64 => {
    const toBlobFn = base64 => {
        const base64Arr = base64.split(',')
        let type = ''
        let base64String = ''
        if (base64Arr.length > 1) {
            // 如果是图片base64，去掉头信息
            base64String = base64Arr[1]
            type = base64Arr[0].substring(base64Arr[0].indexOf(':') + 1, base64Arr[0].indexOf(';'))
        }
        const bytes = atob(base64String)
        const bytesCode = new ArrayBuffer(bytes.length)
        const byteArray = new Uint8Array(bytesCode)

        // 将base64转换为ascii码
        for (let i = 0; i < bytes.length; i++) {
            byteArray[i] = bytes.charCodeAt(i)
        }

        // 生成Blob对象（文件对象）
        return new Blob([bytesCode], {
            type: type
        })
    }
    return Array.isArray(base64) ? base64.map(item => toBlobFn(item)) : toBlobFn(base64)
}

/**
 * 图片URL转base64
 * @param {String} url
 * @param {Function} 格式化
 * @reutrn {String}
 */
export const imgUrlToBase64 = (url, format) => {
    return new Promise(async resolve => {
        try {
            const img = await createImg(url)
            let canvas = createCanvas({ width: img.width, height: img.height })
            const ctx = canvas.getContext('2d')
            ctx.drawImage(img, 0, 0)
            const dataURL = canvas.toDataURL(format || 'image/png')
            canvas = null
            resolve(dataURL)
        } catch (error) {
            console.log(error)
            resolve('')
        }
    })
}

/**
 * 图片压缩
 * @param {String/Array} src 图片地址
 * @param {Number} scale 压缩比例 0-1
 * @returns {Promise}
 */
export const imgCompress = (src, scale = 1) => {
    const imgList = Array.isArray(src) ? src : [src]
    const imgPromList = imgList.map(img => {
        return new Promise(async resolve => {
            const imgEl = await createImg(img)
            const { width, height } = imgEl
            const comWidth = width * scale // 压缩后宽
            const comHeight = height * scale // 压缩后高
            const canvas = createCanvas({ width: comWidth, height: comHeight })
            const ctx = canvas.getContext('2d')
            ctx.clearRect(0, 0, comWidth, comHeight)
            ctx.drawImage(imgEl, 0, 0, comWidth, comHeight)
            resolve({
                ctx,
                data: canvas.toDataURL('image/jpeg', 1)
            })
        })
    })
    return Promise.all(imgPromList).then(res => Promise.resolve(res))
}


/**
 * 获取图片宽、高、大小
 * @param {String} url 文件路径
 * @return {Promise} 宽高相关信息
 */
export const getImageSize = url => {
    return new Promise(resolve => {
        const defaultRes = { width: 0, height: 0, size: 0 } // 默认返回数据
        const img = new Image()
        img.onload = async () => {
            try {
                const imgBase64 = await imgUrlToBase64(url) // 图片转为base64
                const imgBlob = await base64ToBlob(imgBase64) // base64转为流，流中可获取size
                resolve({ width: img.width, height: img.height, size: imgBlob.size })
            } catch (error) {
                console.log(error)
                resolve(defaultRes)
            }
        }

        // 加载错误
        img.onerror = () => {
            console.log(`图片【${url}】加载错误！`)
            resolve(defaultRes)
        }

        img.src = url
    })
}

/**
 * 通过url获取图片base64
 * @param {String} img 图片地址
 * @return {Promise}
 */
export const getImgBase64ByUrl = img => {
    return new Promise(resolve => {
        const image = new Image()

        // 给img设置crossOrigin属性解决跨域
        image.crossOrigin = ''
        image.src = formatUrl(img, { img_time: Date.now() })
        image.onload = () => {
            resolve(getBase64Image(image))
        }
        image.onerror = err => {
            console.log(err)
            resolve(null)
        }
    })
}
